/**  
  -- The Performance Driven Lime Project -- 

  A self adaptive tuple space for mobile agents and hosts by dynamic
  adapting tuple's replication policy.
  
  Copyright (C) 2008
  Xing Jiankuan, Pan Wenhui
  SAGroup of Tsinghua University

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.

  You should have received this copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 */
package sagroup.dracots.testing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;


import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import sagroup.dracots.DracoTS;
import sagroup.dracots.DracoTuple;
import sagroup.dracots.ShareTuple;
import sagroup.dracots.TupleType;
import sagroup.dracots.policy.ReplicationPolicy;

import lime2.LimeServerID;
import lime2.Location;

/**
 * This is the visual agent to show the information as following:
 * 1. Basic information about the local host and DracoTS
 * 2. All engaged hosts of this LIME server
 * 3. All Replication policies of this/remote LIME server
 * 4. All tuples in this LIME server
 * The element of panel is defined in BasicDashBoard class 
 *  
 * @author Jinxue Zhang
 * 
 */

public class VisualAgentNew extends JFrame implements Runnable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -2471549293910919224L;

	// Get DracoTS
	private DracoTS dts = null;
	// the name of DracoTS
	String dtsName = "testing";
	
	//	The panel for information
	JPanel panelInfo = new JPanel();
	
	/*
	 * The following is the basic dashboard element
	 */
	BasicDashboard 
	//	The panel for engaged hosts;
	panelEngaged = new BasicDashboard("All Engaged Hosts"),
	//	The panel for Replication Policy Tuples;	
	panelRTuple  = new BasicDashboard("All Replica Policies"),
	//	The panel for all local Flat Tuples by RDG;	
	panelAllTuple = new BasicDashboard("All Local Tuples");
	
	/*
	 * Close the visual agent frame.
	 */
	class MyWindowAdapter extends WindowAdapter {
		public void windowClosing(WindowEvent we) {
			System.out.println("\nExit DracoTS: " + Location.HERE.toString());
			dispose();
			System.exit(0);
		}
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		//this.setLayout(new BorderLayout());
		this.setSize(1000, 800);
		this.setTitle("New Visual Agent");
		
		/* 
		 * The information panel
		 * 
		 */
		System.out.println("VisualAgent: " + Location.HERE.toString()
				+ " has been started.");
		JLabel 
		//	Start information
		startInfo = new JLabel(),
		//	Local Host info
		localHost = new JLabel();
		// kill button
		JButton killButton = new JButton();
		
		try {
			// Here to get a DracoTupleSpace instance named testing.
			dts = DracoTS.get(dtsName);
			startInfo.setForeground(Color.BLUE);
			startInfo.setText("        Get DracoTS '" + dtsName + "' Successfully.");
			startInfo.setFont(new Font("Arial", Font.PLAIN, 18));
			System.out.println("Get DracoTS '" + dtsName + "' Successfully.");
			
			//dts.setMonitorStatus(true);
			localHost.setForeground(Color.BLUE);
			localHost.setFont(new Font("Arial", Font.PLAIN, 18));
			localHost.setText("        " + "Local Host:  " + Location.HERE.toString());
			
			killButton.setFont(new Font("High Tower Text", Font.BOLD, 14));
			killButton.setForeground(new Color(255, 51, 51));
			killButton.setText("Kill VisualAgent");
			killButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.out.println("\nExit VisualAgent: "
							+ Location.HERE.toString());
					dispose();
				}
			});

		} catch (Exception e) {
			System.out.println("Operation failed!");
			startInfo.setForeground(Color.RED);
			startInfo.setText("Fail to Get DracoTs");
			e.printStackTrace();
		}
		
		panelInfo.setLayout(new BorderLayout());
		panelInfo.add(BorderLayout.WEST, localHost);
		panelInfo.add(startInfo);
		panelInfo.add(BorderLayout.EAST, killButton);

		/*
		 * The engaged hosts
		 */
		getEngagedHosts(panelEngaged.getListModel());
		panelEngaged.getRefreshButton().addActionListener(
				new allEngagedHosts(panelEngaged.getListModel()));
		
		/*
		 * All replica policies
		 */
		getRPs(panelRTuple.getListModel());
		panelRTuple.getRefreshButton().addActionListener(
				new allRPs(panelRTuple.getListModel()));
		
		/*
		 * All tuples
		 */
		getAllTuples(panelAllTuple.getListModel());
		panelAllTuple.getRefreshButton().addActionListener(
				new allTuples(panelAllTuple.getListModel()));
		
		/*
		 * Set the layout
		 * We just use Flow Layout and Border Layout
		 */
		this.add(BorderLayout.NORTH, panelInfo);
		
		JPanel tmpPanel1 = new JPanel(new FlowLayout());
		tmpPanel1.add(panelEngaged);
		tmpPanel1.add(panelRTuple);
		
		JPanel tmpPanel2 = new JPanel(new BorderLayout());
		tmpPanel2.add(BorderLayout.NORTH, tmpPanel1);
		tmpPanel2.add(panelAllTuple);
		this.add(tmpPanel2);
	
		this.addWindowListener(new MyWindowAdapter());
		this.setVisible(true);
	}

	/*
	 *	Get all the engaged hosts 
	 */
	private void getEngagedHosts(DefaultListModel model){
		
		LimeServerID[] tempServers = dts.getAllEngagedHosts();
		model.removeAllElements();
		for (int ix = 0; ix < tempServers.length; ++ix) {
			model.addElement(tempServers[ix].toString());
		}
	}
	
	/*
	 * Action listener for engaged hosts
	 */
	public class allEngagedHosts implements ActionListener{
		private DefaultListModel listModel = null;
		public allEngagedHosts(DefaultListModel aListModel){
			listModel = aListModel;
		}
		public void actionPerformed(ActionEvent e){
			 getEngagedHosts(listModel);
		}
	}
	
	/*
	 * Get all the replica policies
	 */
	void getRPs(DefaultListModel model){
		HashMap<TupleType, HashMap<Location, ReplicationPolicy>> policyMap = dts.getPolicyRegistrar().getAllReplicaPolicy();
		System.out.println("Show the contents of replicaRegistra.");
		model.removeAllElements();
		for (TupleType type : policyMap.keySet()) {
			model.addElement("Type = " + type + " ,");
			HashMap<Location, ReplicationPolicy> inner = policyMap.get(type);
			if (inner != null) {
				for (Location loc : inner.keySet())
					model.addElement("    Location = " + loc
							+ " and Replication Policy = " + inner.get(loc));
			}
		}
	}
	
	/*
	 * Action listener for RP tuples
	 */
	public class allRPs implements ActionListener{
		private DefaultListModel listModel = null;
		public allRPs(DefaultListModel aListModel){
			listModel = aListModel;
		}
		public void actionPerformed(ActionEvent e){
			getRPs(listModel);
		}
	}
	
	/*
	 * Get all the tuples
	 */
	void getAllTuples(DefaultListModel model){
		DracoTuple[] dt = dts.rdg(DracoTuple.createMatchAllLocalTemplate());
		int isReplica = 0;
		
		System.out.println("Show all the tuples");
		model.removeAllElements();
		if (dt != null) {
			model.addElement(String.format("TYPE | VID | CLZ | TID | Is Replica"));
			for (int i = 0; i < dt.length; ++i){
				DracoTuple tmpDT = dt[i];
				if((tmpDT instanceof ShareTuple)){
					if(((ShareTuple) tmpDT).isReplica())
						isReplica = 1;
				}
				model.addElement(String.format("%s | %s | %s | %s | %d", 
						tmpDT.getType(), tmpDT.getVID(), tmpDT.getClzName(),
						tmpDT.getLimeWrapper().id.toString(),
						isReplica
						));
			}
		} else
			model.addElement("No tuples found.");
	}
	
	/*
	 * Action listener for all tuples
	 */
	public class allTuples implements ActionListener{
		private DefaultListModel listModel = null;
		public allTuples(DefaultListModel aListModel){
			listModel = aListModel;
		}
		public void actionPerformed(ActionEvent e){
			getAllTuples(listModel);
		}
	}
}